home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / qdeck / print / xprint.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-11  |  19.8 KB  |  791 lines

  1. /**************************************************************************
  2.  *
  3.  * FILENAME:    xprint.c
  4.  *
  5.  * DESCRIPTION:
  6.  *  Program to demonstrate the use of X Printing as implemented in
  7.  *  DESQview/X.
  8.  *
  9.  * PUBLIC FUNCTIONS:
  10.  *  None
  11.  *
  12.  * NOTES:
  13.  *  Syntax: xprint [-printer <printer>] [-size <font size>] filename.ext
  14.  *
  15.  *  This version does not take wildcards or multiple filenames.
  16.  *  This version does not handle formfeed characters as such.
  17.  *
  18.  *  Copyright (c) Quarterdeck Office Systems, Inc. 1992
  19.  *
  20.  * PVCS INFO:
  21.  *  $Header::   C:/wip/xprint/vcs/xprint.c_v   1.0   19 May 1992 11:18:52 $
  22.  *
  23.  * CHANGES:
  24.  *  $Log::   C:/wip/xprint/vcs/xprint.c_v                                 $
  25.  *
  26.  *     Rev 1.0   19 May 1992 11:18:52   BRIAN
  27.  *  Initial revision.
  28.  *
  29.  **************************************************************************
  30.  
  31. static char id_xprint_c[3][] =  {
  32.                                 "$Workfile::   xprint.c                 $",
  33.                                 "$Revision::   1.0                      $",
  34.                                 "    $Date::   19 May 1992 11:18:52     $"
  35.                                 };
  36.  
  37. /*----- compilation and control switches --------------------------------*/
  38.  
  39.  
  40. /**************************************************************************
  41.  *  INCLUDE FILES
  42.  *************************************************************************/
  43.  
  44. /*----- system and platform files ---------------------------------------*/
  45.  
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48. #include <string.h>
  49.  
  50. #include <X11/Xlib.h>
  51.  
  52. /*----- program files ---------------------------------------------------*/
  53.  
  54.  
  55. /**************************************************************************
  56.  *  EXTERNAL REFERENCES
  57.  *************************************************************************/
  58.  
  59. /*----- data declarations -----------------------------------------------*/
  60.  
  61. /*----- function prototypes ---------------------------------------------*/
  62.  
  63.  
  64. /**************************************************************************
  65.  *  PUBLIC DECLARATIONS
  66.  *************************************************************************/
  67.  
  68. /*----- context ---------------------------------------------------------*/
  69.  
  70. /*----- data declarations -----------------------------------------------*/
  71.  
  72. /*----- function prototypes ---------------------------------------------*/
  73.  
  74.  
  75. /**************************************************************************
  76.  *  PRIVATE DECLARATIONS
  77.  *************************************************************************/
  78.  
  79. /*----- context ---------------------------------------------------------*/
  80.  
  81. #define LOCAL_PRINTER       ":7"
  82. #define DOS_FONT_NAME    "-adobe-lettergothic-Bold-r-normal--0-%d-%d-%d-c-0-iso8859-1"
  83. #define DEFAULT_FONT_SIZE   10.0
  84. #define INCHES_PER_MM       25.4
  85. #define INPUT_BUFFER_LENGTH 512
  86. #define OUTPUT_BUFFER_LENGTH    512
  87. #define TAB_SIZE            8
  88.  
  89. typedef enum
  90. {
  91.     FALSE = 0, TRUE
  92. }               BOOL;
  93.  
  94. /*----- data declarations -----------------------------------------------*/
  95.  
  96. /*----- Set as a result of command line options. ------------------------*/
  97.  
  98. char           *pPrinterName = (char *) NULL;    /* Display name for prtr */
  99. double          FontSize = DEFAULT_FONT_SIZE;    /* Font size in points.  */
  100. char           *pFilename = (char *) NULL;    /* Filename to print. */
  101.  
  102. /*----- X data structures for printing. ---------------------------------*/
  103.  
  104. Display        *pPrinter;        /* X display for printer. */
  105. Window          Page;            /* X window for printer. */
  106. XFontStruct    *pFontInfo;        /* X font info struct for printer font. */
  107. GC              PrintContext;    /* X graphics context for printer. */
  108.  
  109. /*----- Page size information. ------------------------------------------*/
  110.  
  111. unsigned int    PageWidthInPixels;    /* Width of printer page in pixels. */
  112. unsigned int    PageHeightInPixels;    /* Height of printer page in pixels. */
  113.  
  114. /*----- function prototypes ---------------------------------------------*/
  115.  
  116. int             main(int argc, char **argv);
  117. void            ParseArguments(int argc, char **argv);
  118. void            Usage(void);
  119. void            PrintFile(char *pFilename);
  120. void            StartPrintJob(void);
  121. BOOL            PrintPage(FILE * pFile);
  122. int             PrepareLine(char *pInput, char *pOutput);
  123. void            EjectPage(void);
  124. void            FinishPrintJob(void);
  125.  
  126. /*----- macros ----------------------------------------------------------*/
  127.  
  128.  
  129.  
  130. /**************************************************************************
  131.  *  PUBLIC FUNCTION DECLARATIONS
  132.  *************************************************************************/
  133.  
  134.  
  135. /**************************************************************************
  136.  *  PRIVATE FUNCTION DECLARATIONS
  137.  *************************************************************************/
  138.  
  139.  
  140. /**************************************************************************
  141.  * NAME:
  142.  *  main(int argc, char **argv)
  143.  *
  144.  * DESCRIPTION:
  145.  *  Program entry point.
  146.  *
  147.  * INPUTS:
  148.  *  PARAMATERS:
  149.  *      int    argc     Count of command line arguments
  150.  *      char **argv     Array of pointers to command line argument strings
  151.  *
  152.  *  GLOBALS:
  153.  *      None
  154.  *
  155.  * OUTPUTS:
  156.  *  PARAMATERS:
  157.  *      None
  158.  *
  159.  *  GLOBALS:
  160.  *      None
  161.  *
  162.  *  RETURN:
  163.  *      Exits to DOS on completion.
  164.  *
  165.  * NOTES:
  166.  *  Proposed enhancements
  167.  *      Allow for printing of multiple files.
  168.  *
  169.  * CHANGES:
  170.  *  None
  171.  */
  172.  
  173. int
  174. main(int argc, char **argv)
  175. {
  176.  
  177.     /*********************************************************************/
  178.  
  179.  
  180.     /****** CODE *********************************************************/
  181.  
  182.     ParseArguments(argc, argv);
  183.  
  184.     PrintFile(pFilename);
  185.  
  186.     exit(0);
  187. }
  188.  
  189.  
  190. /**************************************************************************
  191.  * NAME:
  192.  *  ParseArguments(int argc, char ** argv)
  193.  *
  194.  * DESCRIPTION:
  195.  *  Parse command line arguments and set corresponding global variables.
  196.  *
  197.  * INPUTS:
  198.  *  PARAMATERS:
  199.  *      int    argc     Count of command line arguments
  200.  *      char **argv     Array of pointers to command line argument strings
  201.  *
  202.  *  GLOBALS:
  203.  *      None
  204.  *
  205.  * OUTPUTS:
  206.  *  PARAMATERS:
  207.  *      None
  208.  *
  209.  *  GLOBALS:
  210.  *      char  *pPrinterName     Pointer to display name for printer.
  211.  *      double FontSize         Font size to use when printing in points
  212.  *      char  *pFilename        Pointer to name of file to print.
  213.  *
  214.  *  RETURN:
  215.  *      None
  216.  *
  217.  * NOTES:
  218.  *  Proposed enhancements
  219.  *      Allow for abbreviations of command line switches.
  220.  *      Make command line switches case insensitive.
  221.  *      Allow for printing of multiple files.
  222.  *      Allow for wildcarding of filenames.
  223.  *
  224.  * CHANGES:
  225.  *  None
  226.  */
  227.  
  228. void
  229. ParseArguments(int argc, char **argv)
  230. {
  231.  
  232.     /*********************************************************************/
  233.  
  234.     int             ArgumentIndex;
  235.  
  236.     /****** CODE *********************************************************/
  237.  
  238.     for (ArgumentIndex = 1; ArgumentIndex < argc; ArgumentIndex++)
  239.         {
  240.         if (strcmp(argv[ArgumentIndex], "-printer") == 0)
  241.             {
  242.             if (++ArgumentIndex >= argc)
  243.                 Usage();
  244.  
  245.             pPrinterName = argv[ArgumentIndex];
  246.  
  247.             continue;
  248.             }
  249.  
  250.         if (strcmp(argv[ArgumentIndex], "-size") == 0)
  251.             {
  252.             if (++ArgumentIndex >= argc)
  253.                 Usage();
  254.  
  255.             FontSize = atof(argv[ArgumentIndex]);
  256.  
  257.             continue;
  258.             }
  259.  
  260.         pFilename = argv[ArgumentIndex];
  261.         }
  262.  
  263.     if (pFilename == (char *) NULL)
  264.         Usage();
  265. }
  266.  
  267.  
  268. /**************************************************************************
  269.  * NAME:
  270.  *  Usage(void)
  271.  *
  272.  * DESCRIPTION:
  273.  *  Prints usage message and then exits to DOS.
  274.  *
  275.  * INPUTS:
  276.  *  PARAMATERS:
  277.  *      None
  278.  *
  279.  *  GLOBALS:
  280.  *      None
  281.  *
  282.  * OUTPUTS:
  283.  *  PARAMATERS:
  284.  *      None
  285.  *
  286.  *  GLOBALS:
  287.  *      None
  288.  *
  289.  *  RETURN:
  290.  *      None
  291.  *
  292.  * NOTES:
  293.  *  This should be updated when command line switches are added.
  294.  *
  295.  * CHANGES:
  296.  *  None
  297.  */
  298.  
  299. void
  300. Usage(void)
  301. {
  302.  
  303.     /*********************************************************************/
  304.  
  305.  
  306.     /****** CODE *********************************************************/
  307.  
  308.     fprintf(stderr, "usage: xprint [-printer <printer>] [-size <font size in points>] filename.ext\n");
  309.  
  310.     exit(1);
  311. }
  312.  
  313.  
  314. /**************************************************************************
  315.  * NAME:
  316.  *  PrintFile(char *pFilename)
  317.  *
  318.  * DESCRIPTION:
  319.  *  Print the file whose name is pointed at by pFilename to the X printer
  320.  *
  321.  * INPUTS:
  322.  *  PARAMATERS:
  323.  *      char  *pFilename        Pointer to name of file to print.
  324.  *
  325.  *  GLOBALS:
  326.  *      None
  327.  *
  328.  * OUTPUTS:
  329.  *  PARAMATERS:
  330.  *      None
  331.  *
  332.  *  GLOBALS:
  333.  *      None
  334.  *
  335.  *  RETURN:
  336.  *      None
  337.  *
  338.  * NOTES:
  339.  *  This is the topmost routine that actually handles the printing of
  340.  *  files.  It's purpose is to start the print job, print and eject each
  341.  *  page in turn.  After we print the last page, instead of ejecting it
  342.  *  explicitly, we finish the print job which will automatically eject the
  343.  *  final page.
  344.  *
  345.  * CHANGES:
  346.  *  None
  347.  */
  348.  
  349. void
  350. PrintFile(char *pFilename)
  351. {
  352.  
  353.     /*********************************************************************/
  354.  
  355.     FILE           *pFile;        /* FILE * for file being printed. */
  356.     BOOL            LastPage;    /* Flag indicating that the file is done */
  357.  
  358.     /****** CODE *********************************************************/
  359.  
  360.     /*----- Open file for printing. -------------------------------------*/
  361.  
  362.     pFile = fopen(pFilename, "rb");
  363.  
  364.     if (pFile == (FILE *) NULL)
  365.         {
  366.         fprintf(stderr, "Unable to open file: %s\n", pFilename);
  367.         return;
  368.         }
  369.  
  370.     /*----- Print File. -------------------------------------------------*/
  371.  
  372.     fprintf(stdout, "Printing %s\n", pFilename);
  373.  
  374.     StartPrintJob();
  375.  
  376.     do
  377.         {
  378.         LastPage = PrintPage(pFile);
  379.  
  380.         if (LastPage == FALSE)
  381.             EjectPage();
  382.  
  383.         } while (LastPage == FALSE);
  384.  
  385.     FinishPrintJob();
  386.  
  387.     fclose(pFile);
  388. }
  389.  
  390.  
  391. /**************************************************************************
  392.  * NAME:
  393.  *  StartPrintJob(void)
  394.  *
  395.  * DESCRIPTION:
  396.  *  Connect to X Print Server and setup up printing environment.
  397.  *
  398.  * INPUTS:
  399.  *  PARAMATERS:
  400.  *      None
  401.  *
  402.  *  GLOBALS:
  403.  *      char  *pPrinterName     Pointer to display name for printer.
  404.  *      double FontSize         Font size to use when printing (in points).
  405.  *
  406.  * OUTPUTS:
  407.  *  PARAMATERS:
  408.  *      None
  409.  *
  410.  *  GLOBALS:
  411.  *      Display     *pPrinter;              X display for printer.
  412.  *      Window       Page;                  X window for printer.
  413.  *      XFontStruct *pFontInfo;             X font info for printer font.
  414.  *      GC           PrintContext;          X graphics context for printer.
  415.  *      unsigned int PageWidthInPixels      Width of print page in pixels.
  416.  *      unsigned int PageHeightInPixels     Height of print page in pixels.
  417.  *
  418.  *  RETURN:
  419.  *      None
  420.  *
  421.  * NOTES:
  422.  *  Basic steps for starting print job.
  423.  *      Connect to X Print Server.
  424.  *      Query for page size and resolution.
  425.  *      Create window that will represent the printed page.
  426.  *      Create X font string and load printer font.
  427.  *      Create graphics context for printing.
  428.  *
  429.  * CHANGES:
  430.  */
  431.  
  432. void
  433. StartPrintJob(void)
  434. {
  435.  
  436.     /*********************************************************************/
  437.  
  438.     unsigned int    XResolution;/* X resolution of printer. */
  439.     unsigned int    YResolution;/* Y resolution of printer. */
  440.  
  441.     char            FontNameBuffer[128];    /* X font string. */
  442.     int             ScreenNumber;    /* X screen number for printer. */
  443.     XGCValues       GCValues;    /* Initial values for printer GC when it is
  444.                                  * created. */
  445.  
  446.     /****** CODE *********************************************************/
  447.  
  448.     /*----- Establish connection to X Print Server ----------------------*/
  449.  
  450.     if (pPrinterName == (char *) NULL)
  451.         pPrinterName = LOCAL_PRINTER;
  452.  
  453.     pPrinter = XOpenDisplay(pPrinterName);
  454.  
  455.     if (pPrinter == NULL)
  456.         {
  457.         fprintf(stderr,
  458.                 "xprint: cannot connect to X printer %s\n",
  459.                 pPrinterName);
  460.  
  461.         exit(-1);
  462.         }
  463.  
  464.  
  465.     /*----- Query information from XLib ---------------------------------*/
  466.  
  467.     ScreenNumber = DefaultScreen(pPrinter);
  468.  
  469.     PageWidthInPixels = DisplayWidth(pPrinter, ScreenNumber);
  470.  
  471.     PageHeightInPixels = DisplayHeight(pPrinter, ScreenNumber);
  472.  
  473.     XResolution = (unsigned int) ((PageWidthInPixels * INCHES_PER_MM)
  474.                                   / DisplayWidthMM(pPrinter, ScreenNumber));
  475.  
  476.     YResolution = (unsigned int) ((PageHeightInPixels * INCHES_PER_MM)
  477.                                   / DisplayHeightMM(pPrinter, ScreenNumber));
  478.  
  479.  
  480.     /*----- Create window that will represent the printed page. ---------*/
  481.  
  482.     Page = XCreateSimpleWindow(pPrinter,
  483.                                RootWindow(pPrinter, ScreenNumber),
  484.                                0,
  485.                                0,
  486.                                PageWidthInPixels,
  487.                                PageHeightInPixels,
  488.                                0,
  489.                                BlackPixel(pPrinter, ScreenNumber),
  490.                                WhitePixel(pPrinter, ScreenNumber));
  491.  
  492.  
  493.     /*----- Create X font string and load printer font. -----------------*/
  494.  
  495.     sprintf(FontNameBuffer, DOS_FONT_NAME, (int) (FontSize * 10),
  496.             XResolution, YResolution);
  497.  
  498.     pFontInfo = XLoadQueryFont(pPrinter, FontNameBuffer);
  499.  
  500.     if (pFontInfo == (XFontStruct *) NULL)
  501.         {
  502.         fprintf(stderr, "xprint: Unable to load font: %s\n", FontNameBuffer);
  503.         exit(-1);
  504.         }
  505.  
  506.  
  507.     /*----- Create printer graphics context. ----------------------------*/
  508.  
  509.     GCValues.font = pFontInfo->fid;
  510.  
  511.     PrintContext = XCreateGC(pPrinter, Page, GCFont, &GCValues);
  512. }
  513.  
  514.  
  515. /**************************************************************************
  516.  * NAME:
  517.  *  PrintPage(FILE *pFile)
  518.  *
  519.  * DESCRIPTION:
  520.  *  Output text to the printer for the current page.
  521.  *
  522.  * INPUTS:
  523.  *  PARAMATERS:
  524.  *      FILE *pFile;        FILE * for file currently being printed.
  525.  *
  526.  *  GLOBALS:
  527.  *      Display     *pPrinter;              X display for printer.
  528.  *      Window       Page;                  X window for printer.
  529.  *      XFontStruct *pFontInfo;             X font info for printer font.
  530.  *      GC           PrintContext;          X graphics context for printer.
  531.  *      unsigned int PageHeightInPixels     Height of print page in pixels.
  532.  *
  533.  * OUTPUTS:
  534.  *  PARAMATERS:
  535.  *      pFile is advanced to the beginning of the next page or the end
  536.  *      of the file.
  537.  *
  538.  *  GLOBALS:
  539.  *      None
  540.  *
  541.  *  RETURN:
  542.  *      Boolean value indicating that the last page has been printed.
  543.  *
  544.  * NOTES:
  545.  *  This function calls PrepareLine() in order to exapand tabs into spaces
  546.  *  and strips linefeed characters so that we don't end up using the X
  547.  *  glyphs for these characters.
  548.  *
  549.  *  This function uses the XFontInfo structure elements ascent and descent
  550.  *  which added together make up the height of the font bounding box in
  551.  *  order to determine the vertical positioning of the text which is output
  552.  *  using XDrawString().
  553.  *
  554.  * CHANGES:
  555.  *  None
  556.  */
  557.  
  558. BOOL
  559. PrintPage(FILE * pFile)
  560. {
  561.  
  562.     /*********************************************************************/
  563.  
  564.     unsigned int    XPos;        /* Current logical cursor X position. */
  565.     unsigned int    YPos;        /* Current logical cursor Y position. */
  566.  
  567.     int             StringLength;    /* length of string being output. */
  568.  
  569.     char            InputBuffer[INPUT_BUFFER_LENGTH];
  570.     char            OutputBuffer[OUTPUT_BUFFER_LENGTH];
  571.  
  572.     /****** CODE *********************************************************/
  573.  
  574.     for (XPos = 0, YPos = pFontInfo->ascent;
  575.          (YPos + pFontInfo->descent) < PageHeightInPixels;
  576.          YPos += (pFontInfo->ascent + pFontInfo->descent))
  577.         {
  578.         if (fgets(InputBuffer, INPUT_BUFFER_LENGTH, pFile) == (char *) NULL)
  579.             return (TRUE);
  580.  
  581.         StringLength = PrepareLine(InputBuffer, OutputBuffer);
  582.  
  583.         XDrawString(pPrinter,
  584.                     Page,
  585.                     PrintContext,
  586.                     XPos,
  587.                     YPos,
  588.                     OutputBuffer,
  589.                     StringLength);
  590.         }
  591.  
  592.     return (FALSE);
  593. }
  594.  
  595.  
  596. /**************************************************************************
  597.  * NAME:
  598.  *  PrepareLine(char *pInput, char *pOutput)
  599.  *
  600.  * DESCRIPTION:
  601.  *  Prepares line for X printing by stripping out nonprinting positioning
  602.  *  characters like newlines and tabs.
  603.  *
  604.  * INPUTS:
  605.  *  PARAMATERS:
  606.  *      char *pInput        Pointer to input string.
  607.  *      char *pOutput       Pointer to output buffer.
  608.  *
  609.  *  GLOBALS:
  610.  *      None
  611.  *
  612.  * OUTPUTS:
  613.  *  PARAMATERS:
  614.  *      pOutput buffer contains the modified version of the pInput string.
  615.  *
  616.  *  GLOBALS:
  617.  *      None
  618.  *
  619.  *  RETURN:
  620.  *      Number of characters in output buffer.
  621.  *
  622.  * NOTES:
  623.  *  Certain characters that are used for positioning text in a text file
  624.  *  can have X glyphs associated with them.  Some of these characters
  625.  *  include tabs and linefeeds.  Since we are using the XLib functions for
  626.  *  positioning and displaying text we will strip these characters out of
  627.  *  the text so that we don't get unexpected characters in our printout.
  628.  *
  629.  *  We convert tabs into spaces and strip the linefeeds.
  630.  *
  631.  * CHANGES:
  632.  *  None
  633.  */
  634.  
  635. int
  636. PrepareLine(char *pInput, char *pOutput)
  637. {
  638.  
  639.     /*********************************************************************/
  640.  
  641.     int             CharCount;    /* Count of characters in output buffer. */
  642.     char            CurrChar;    /* Current input character. */
  643.  
  644.     /****** CODE *********************************************************/
  645.  
  646.     for (CharCount = 0; CharCount < OUTPUT_BUFFER_LENGTH - 1;)
  647.         {
  648.         CurrChar = *pInput++;
  649.  
  650.         switch (CurrChar)
  651.             {
  652.           case '\0':
  653.           case '\n':
  654.           case '\r':
  655.  
  656.             goto line_ready;
  657.  
  658.           case '\t':
  659.  
  660.             do
  661.                 {
  662.  
  663.                 *pOutput++ = ' ';
  664.  
  665.                 } while ((++CharCount % TAB_SIZE) != 0);
  666.  
  667.             break;
  668.  
  669.           default:
  670.  
  671.             *pOutput++ = CurrChar;
  672.             CharCount++;
  673.             }
  674.         }
  675.  
  676. line_ready:
  677.  
  678.     *pOutput = '\0';
  679.  
  680.     return (CharCount);
  681. }
  682.  
  683.  
  684. /**************************************************************************
  685.  * NAME:
  686.  *  EjectPage(void)
  687.  *
  688.  * DESCRIPTION:
  689.  *  Eject the current page.
  690.  *
  691.  * INPUTS:
  692.  *  PARAMATERS:
  693.  *      None
  694.  *
  695.  *  GLOBALS:
  696.  *      Display *pPrinter       X display for printer.
  697.  *      Window   Page           X window for printer.
  698.  *
  699.  * OUTPUTS:
  700.  *  PARAMATERS:
  701.  *      None
  702.  *
  703.  *  GLOBALS:
  704.  *      None
  705.  *
  706.  *  RETURN:
  707.  *      None
  708.  *
  709.  * NOTES:
  710.  *  In order to eject a page and begin a new one we call XMapWindow().
  711.  *  In effect, this maps the window to the printer.
  712.  *
  713.  * CHANGES:
  714.  *  None
  715.  */
  716.  
  717. void
  718. EjectPage(void)
  719. {
  720.  
  721.     /*********************************************************************/
  722.  
  723.  
  724.     /****** CODE *********************************************************/
  725.  
  726.     XMapWindow(pPrinter, Page);
  727. }
  728.  
  729.  
  730. /**************************************************************************
  731.  * NAME:
  732.  *  FinishPrintJob(void)
  733.  *
  734.  * DESCRIPTION:
  735.  *  Closes connection to X Print Server.
  736.  *
  737.  * INPUTS:
  738.  *  PARAMATERS:
  739.  *      None
  740.  *
  741.  *  GLOBALS:
  742.  *      Display     *pPrinter               X display for printer
  743.  *      Window       Page;                  X window for printer.
  744.  *      XFontStruct *pFontInfo;             X font info for printer font.
  745.  *      GC           PrintContext;          X graphics context for printer.
  746.  *
  747.  * OUTPUTS:
  748.  *  PARAMATERS:
  749.  *      None
  750.  *
  751.  *  GLOBALS:
  752.  *      None
  753.  *
  754.  *  RETURN:
  755.  *      None
  756.  *
  757.  * NOTES:
  758.  *  An X print job is finished when the connection to the X Print Server is
  759.  *  closed.  A side effect of this is that the last page is automatically
  760.  *  ejected.
  761.  *
  762.  * CHANGES:
  763.  *  None
  764.  */
  765.  
  766. void
  767. FinishPrintJob(void)
  768. {
  769.  
  770.     /*********************************************************************/
  771.  
  772.  
  773.     /****** CODE *********************************************************/
  774.  
  775.     /*----- Free graphics context ---------------------------------------*/
  776.  
  777.     XFreeGC(pPrinter, PrintContext);
  778.  
  779.     /*----- Free font ---------------------------------------------------*/
  780.  
  781.     XFreeFont(pPrinter, pFontInfo);
  782.  
  783.     /*----- Free drawing window -----------------------------------------*/
  784.  
  785.     XDestroyWindow(pPrinter, Page);
  786.  
  787.     /*----- Close Display ending print jobs -----------------------------*/
  788.  
  789.     XCloseDisplay(pPrinter);
  790. }
  791.